﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using BooksManager.Data;
using BooksManager.Entities;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

using MQuery;

namespace BooksManager.Controllers
{
    [Route("api/books")]
    [ApiController]
    public class BooksController : ControllerBase
    {
        private readonly AppDbContext _db;

        public ILogger<BooksController> Logger { get; set; }

        public BooksController(AppDbContext db, ILogger<BooksController> logger)
        {
            _db = db;
            Logger = logger;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Book>>> Query(
            Query<Book> queryExpression,
            [FromQuery(Name = "$search")] string search = null
        )
        {
            var qy = _db.Books.OrderBy(e => e.Id).AsQueryable();
            if(search is { })
                qy = qy.Where(e =>
                e.Name.Contains(search)
                || e.Author.Contains(search)
                || e.Tags.Contains(search)
            );
            var result = qy.Query(queryExpression);
            return await result.ToListAsync();
        }

        [HttpGet("{id}")]
        public async Task<ActionResult<Book>> Find(int id)
        {
            var book = await _db.Books.FindAsync(id);
            if(book is null)
                return NotFound();
            return book;
        }

        [HttpPost]
        public async Task<ActionResult<Book>> Create(Book book)
        {
            _db.Add(book);
            await _db.SaveChangesAsync();
            return book;
        }

        [HttpPut("{id}")]
        public async Task<ActionResult<Book>> Update(int id, Book book)
        {
            var old = await _db.Books.FindAsync(id);
            if(old is null)
                return NotFound();
            old.Name = book.Name;
            old.PublicationDate = book.PublicationDate;
            old.Author = book.Author;
            old.Tags = book.Tags;
            await _db.SaveChangesAsync();
            return old;
        }

        [HttpDelete("{id}")]
        public async Task<ActionResult> Delete(int id)
        {
            var book = await _db.Books.FindAsync(id);
            if(book is null)
                return NotFound();
            _db.Remove(book);
            await _db.SaveChangesAsync();
            return Ok();
        }
    }
}
